# -*- coding:utf-8 -*-

#depreated 已经被废弃

import sys
import logging
from numpy import *

from django.db import connection

from wolfox.foxit.dune.models import XDayQuote,StockCode #,Report
from wolfox.foxit.dune.store import NormalStore

logger = logging.getLogger("dune.sql_helper")

class DynData(object):
    ''' 动态向量数据
    '''

    def __init__(self,model,condition_functor,excluded_fields,order_fields=(),mandatory_fields=()):
        ''' model为指定的Model类名
            excluded_fields为不供选择的字段
            condition_functor为根据参数stock_id,begin,end生成条件的函数
            mandatory_field为必须选择的字段,如tdate
        '''
        self.table_name = model._meta.db_table
        all_name = set([field.name for field in model._meta.fields])
        self.fields = all_name - set(excluded_fields)
        self.condition_functor = condition_functor
        self.store = NormalStore()
        self.mandatory_fields = set(mandatory_fields)
        self.order_fields = order_fields
        self.required_fields = self.mandatory_fields.copy()

    def set_required_fields(self,*fields):
        self.required_fields.update(fields)
        assert(self.required_fields.issubset(self.fields))

    def get_arrays(self,stock_code,begin=0,end=99999999):
        ''' 根据stockcode和时间区间[begin,end)返回dict
            该dict的key为field名字,值为相应的序列
            区间保障由condition_functor遵守
        '''
        try:
            #print self.store.get_stockmap()
            stock_id = (self.store.get_stockmap()[stock_code]).id
            condition = self.condition_functor(stock_id,begin,end)
            sfields = ','.join(self.required_fields)
            sql = 'select %s from %s where %s' % (sfields,self.table_name,condition)
            if self.order_fields:
                sql = ' %s order by %s' % (sql,','.join(self.order_fields))
            records = self.store.query(connection,sql)
            #print sql
            return self.records2arrays(records)
        except KeyError,inst:   
            rev = {}
            logger.exception(u'%s存取错误,该股票不存在',stock_code)
        except Exception:   
            logger.exception(u'%s存取错误,sql=%s',stock_code,sql)
            raise
        return rev

    def records2arrays(self,records):
        "这里借用了set的枚举顺序等于','.join时的顺序"
        rarrays = array(records)    #转化为以记录为行的二维数组
        arrays = rarrays.swapaxes(0,1)  #转置之后成为以每个字段的顺序为行的二维数组
        rev = {}
        if arrays.size > 0:
            for nth,key in enumerate(self.required_fields):
                rev[key] = arrays[nth]
        else:
            for nth,key in enumerate(self.required_fields):
                rev[key] = array([],'int32')
        return rev


_xdayquote = DynData(XDayQuote,
        condition_functor=lambda stock_id,begin,end:' tstock_id = %d and tdate>=%d and tdate<%d' % (stock_id,begin,end),
        excluded_fields=('id','tstock'),
        order_fields=('tdate',),
        mandatory_fields=('tdate',))
#_report = DynData(Report,  #获得最新的report
#        condition_functor=lambda stock_id,begin,end : ' tstock_id = %d and tperiod = (select max(tperiod) where tstock_id=%s)'% (stock_id,stock_id),
#        excluded_fields=('id','tstock','announce_day'),
#        mandatory_fields=('tperiod',))

dyn_source = (_xdayquote,)


class BasicData(object):
    ''' 标量基础数据
    '''

    def __init__(self,model,fields,condition):
        ''' model为指定的Model类名
            fields为需要选择的字段. 第一个字段必须为stock_id字段
            condition为合法性条件
        '''
        self.table_name = model._meta.db_table
        self.fields = fields
        assert set(fields).issubset(set([field.name for field in model._meta.fields]))
        self.condition = condition
        self.store = NormalStore()
 
    def get_records(self):
        ''' 返回所有合法数据的相关基础信息
            返回值为dict,键为stock_code,内容为fields[1:]的值
        '''
        rev = {}
        try:
            id2code = self.store.get_id2code()
            sfields = ','.join(self.fields)
            if self.condition:
                sql = 'select %s from %s where %s' % (sfields,self.table_name,self.condition)
            else:
                sql = 'select %s from %s' % (sfields,self.table_name)
            for record in self.store.query(connection,sql):
                #print 'record[0]:%s' % record[0]                 
                rev[id2code[record[0]]] = record
            #print sql
        except Exception:   
            logger.exception(u'存取错误,sql=%s',sql)
            raise
        return rev

_basic = BasicData(StockCode,('id','total_size','outstanding_size'), "exchange_id in ('SHSE','SZSE')")

basic_source = (_basic,)

        
